using Admin2025.Application.common;
using Admin2025.Application.Dtos;
using Admin2025.Domain.Entities.App;
using Admin2025.Domain.Repository;
using Microsoft.EntityFrameworkCore;

namespace Admin2025.Application.Services
{
    public class AppUserService : IAppUserService
    {
        private readonly IRepository<AppUser> _userRepository;
        private readonly IRepository<AppRole> _roleRepository;

        public AppUserService(IRepository<AppUser> userRepository, IRepository<AppRole> roleRepository)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
        }

        // 所有用户
        // public async Task<IEnumerable<UserDto>> GetAllAsync()
        // {
        //     var list = await _userRepository.GetAllAsync();
        //     return list.Select(user => new UserDto
        //     {
        //         Id = user.Id,
        //         Username = user.Username,
        //         Nickname = user.Nickname
        //     });
        // }
        //单个用户
        public async Task<UserDto> GetByIdAsync(Guid id)
        {
            var u = await _userRepository.GetByIdAsync(id) ?? throw new Exception("用户不存在");
            return new UserDto
            {
                Id = u.Id,
                Username = u.Username,
                Nickname = u.Nickname
            };
        }


        // 新增用户
        public async Task CreateAsync(CreateUserDto dto)
        {
            var salt = Guid.NewGuid().ToString("N");
            var pwdHash = HashPassword(dto.Password, salt);
            var user = new AppUser { Username = dto.Username, Password = pwdHash, Salt = salt };
            await _userRepository.CreateAsync(user);
        }
        // 修改用户
        public async Task UpdateAsync(Guid id, UpdateUserDto dto)
        {
            var user = await _userRepository.GetByIdAsync(id) ?? throw new Exception("用户不存在");
            if (!string.IsNullOrEmpty(dto.Nickname)) user.UpdateNickname(dto.Nickname);
            if (!string.IsNullOrEmpty(dto.AvatarUrl)) user.UpdateAvatar(dto.AvatarUrl);
            await _userRepository.UpdateAsync(user);
        }
        // 删除用户
        public async Task DeleteAsync(Guid id)
        {

            var user = await _userRepository.GetByIdAsync(id) ?? throw new Exception("用户不存在");
            await _userRepository.DeleteAsync(user);
        }
        // 启用用户
        public async Task EnableAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id) ?? throw new Exception("用户不存在");
            user.Enable();
            await _userRepository.UpdateAsync(user);
        }
        // 禁用用户
        public async Task<ApiResult> DisableAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null)
            {
                return ApiResult.Fail(ErrorCode.NotFound, "用户不存在或者已删除");
            }
            user.Disable();
            await _userRepository.UpdateAsync(user);
            return ApiResult.Success(user);
        }
        // 分配角色给用户
        public async Task AssignRoleAsync(Guid userId, Guid roleId)
        {
            var user = await _userRepository.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
            var role = await _roleRepository.GetByIdAsync(roleId) ?? throw new Exception("角色不存在");

            user.AssignRole(role);
            await _userRepository.UpdateAsync(user);
        }
        // 移除用户的角色
        public async Task RemoveRoleAsync(Guid userId, Guid roleId)
        {
            var user = await _userRepository.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
            var role = await _roleRepository.GetByIdAsync(roleId) ?? throw new Exception("角色不存在");

            user.RemoveRole(role);
            await _userRepository.UpdateAsync(user);
        }
        // 更新用户头像
        public async Task UpdateAvatarAsync(Guid id, string avatarUrl)
        {
            var user = await _userRepository.GetByIdAsync(id) ?? throw new Exception("用户不存在");
            user.UpdateAvatar(avatarUrl);
            await _userRepository.UpdateAsync(user);
        }
        // 更新用户的昵称
        public async Task UpdateNicknameAsync(Guid id, string nickname)
        {
            var user = await _userRepository.GetByIdAsync(id) ?? throw new Exception("用户不存在");
            user.UpdateNickname(nickname);
            await _userRepository.UpdateAsync(user);
        }
        // 修改密码
        public async Task ChangePasswordAsync(Guid userId, string oldPwd, string newPwd)
        {
            var user = await _userRepository.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
            var oldPwdHash = HashPassword(oldPwd, user.Salt);
            var newPwdHash = HashPassword(newPwd, user.Salt);
            user.ChangePassword(oldPwdHash, newPwdHash);
            await _userRepository.UpdateAsync(user);
        }
        // 哈希密码
        private string HashPassword(string pwd, string salt)
        {
            using var sha256 = System.Security.Cryptography.SHA256.Create();
            var bytes = System.Text.Encoding.UTF8.GetBytes(pwd + salt);
            var hash = sha256.ComputeHash(bytes);
            return Convert.ToBase64String(hash);
        }

        //分页获取用户
        public async Task<PagedResult<UserDto>> GetUsersWithRolesAsync(PageRequestDto dto)
        {
            var query = _userRepository.Table
                .Include(u => u.Roles) // 包含角色信息
                .Select(u => new UserDto
                {
                    Id = u.Id,
                    Username = u.Username,
                    AvatarUrl = u.AvatarUrl,
                    Nickname = u.Nickname,
                    Roles = u.Roles.Select(r => new RoleDto
                    {
                        Id = r.Id,
                        RoleName = r.RoleName
                    }).ToList()
                });

            // 查询功能：如果有关键字，则按用户名或昵称模糊查找
            if (!string.IsNullOrWhiteSpace(dto.Keyword))
            {
                query = query.Where(u => u.Username.Contains(dto.Keyword) || (u.Nickname != null && u.Nickname.Contains(dto.Keyword)));
            }

            var total = await query.CountAsync();
            var items = await query
                .Skip((dto.PageIndex - 1) * dto.PageSize)
                .Take(dto.PageSize)
                .ToListAsync();

            return new PagedResult<UserDto>
            {
                PageIndex = dto.PageIndex,
                PageSize = dto.PageSize,
                TotalCount = total,
                Items = items
            };
        }
        public async Task<PagedResult<UserDto>> GetPagedAsync(PageRequestDto dto)
        {
            return await GetUsersWithRolesAsync(dto);
        }
    }
}